package models

import (
	"database/sql/driver"
	"encoding/json"
	"fmt"
	"time"
)

// TrimSpecifications represents the JSON structure for specifications
type TrimSpecifications struct {
	Categories map[string]SpecCategory `json:"categories"`
}

// SpecCategory represents a category of specifications
type SpecCategory struct {
	CategoryOrder int        `json:"category_order"`
	Items         []SpecItem `json:"items"`
}

// SpecItem represents individual specification item
type SpecItem struct {
	Name         string `json:"name"`
	Value        string `json:"value"`
	Unit         string `json:"unit"`
	DisplayOrder int    `json:"display_order"`
	DataType     string `json:"data_type"` // "numeric", "text", "boolean", "url"
	Tooltip      string `json:"tooltip,omitempty"`
}

// TrimSpecsMetadata represents metadata about specifications
type TrimSpecsMetadata struct {
	TotalCategories  int       `json:"total_categories"`
	TotalSpecs       int       `json:"total_specs"`
	ScrapedAt        time.Time `json:"scraped_at"`
	SourceURL        string    `json:"source_url"`
	ScrapeMethod     string    `json:"scrape_method"`
	DataCompleteness string    `json:"data_completeness"`
}

// Scan implements sql.Scanner interface for TrimSpecifications
func (ts *TrimSpecifications) Scan(value interface{}) error {
	if value == nil {
		*ts = TrimSpecifications{Categories: make(map[string]SpecCategory)}
		return nil
	}

	bytes, ok := value.([]byte)
	if !ok {
		return fmt.Errorf("cannot scan %T into TrimSpecifications", value)
	}

	return json.Unmarshal(bytes, ts)
}

// Value implements driver.Valuer interface for TrimSpecifications
func (ts TrimSpecifications) Value() (driver.Value, error) {
	if len(ts.Categories) == 0 {
		return nil, nil
	}
	return json.Marshal(ts)
}

// Scan implements sql.Scanner interface for TrimSpecsMetadata
func (tsm *TrimSpecsMetadata) Scan(value interface{}) error {
	if value == nil {
		*tsm = TrimSpecsMetadata{}
		return nil
	}

	bytes, ok := value.([]byte)
	if !ok {
		return fmt.Errorf("cannot scan %T into TrimSpecsMetadata", value)
	}

	return json.Unmarshal(bytes, tsm)
}

// Value implements driver.Valuer interface for TrimSpecsMetadata
func (tsm TrimSpecsMetadata) Value() (driver.Value, error) {
	return json.Marshal(tsm)
}

// TrimInfo represents trim information for a vehicle model with JSON specifications
type TrimInfo struct {
	ID                    int      `json:"id" gorm:"column:id;primaryKey;autoIncrement"`
	ModelName             string   `json:"model_name" gorm:"column:model_name;not null;size:100;index"`
	TrimName              string   `json:"trim_name" gorm:"column:trim_name;not null;size:100;index"`
	TrimDisplayName       string   `json:"trim_display_name" gorm:"column:trim_display_name;not null;size:150"`
	Doors                 *int     `json:"doors" gorm:"column:doors"`
	PriceFrom             *float64 `json:"price_from" gorm:"column:price_from;type:decimal(10,2);index"`
	Currency              string   `json:"currency" gorm:"column:currency;size:10;default:GBP"`
	BatteryCapacity       string   `json:"battery_capacity" gorm:"column:battery_capacity;size:50"`
	EnergyConsumption     string   `json:"energy_consumption" gorm:"column:energy_consumption;size:50"`
	CO2Emissions          string   `json:"co2_emissions" gorm:"column:co2_emissions;size:50"`
	ChargingTime          string   `json:"charging_time" gorm:"column:charging_time;size:50"`
	RangeMiles            string   `json:"range_miles" gorm:"column:range_miles;size:50"`
	ImageURL              string   `json:"image_url" gorm:"column:image_url;type:text"`
	ConfigureURL          string   `json:"configure_url" gorm:"column:configure_url;type:text"`
	SeeFullSpecsAvailable bool     `json:"see_full_specs_available" gorm:"column:see_full_specs_available;default:true"`

	// 🔥 新增JSON字段
	Specifications TrimSpecifications `json:"specifications" gorm:"column:specifications;type:json"`
	SpecsMetadata  TrimSpecsMetadata  `json:"specs_metadata" gorm:"column:specs_metadata;type:json"`

	CreatedAt time.Time `json:"created_at" gorm:"column:created_at;autoCreateTime"`
	UpdatedAt time.Time `json:"updated_at" gorm:"column:updated_at;autoUpdateTime"`
	ScrapedAt time.Time `json:"scraped_at" gorm:"column:scraped_at;autoCreateTime"`
}

// TableName specifies the table name for TrimInfo
func (TrimInfo) TableName() string {
	return "trim_info_uk"
}

// 🔥 保留旧的TrimSpecsInfo结构以兼容迁移过程
type TrimSpecsInfo struct {
	ID           int       `json:"id" gorm:"column:id;primaryKey;autoIncrement"`
	TrimName     string    `json:"trim_name" gorm:"column:trim_name;not null;size:100;index"`
	ModelName    string    `json:"model_name" gorm:"column:model_name;not null;size:100;index"`
	SpecCategory string    `json:"spec_category" gorm:"column:spec_category;not null;size:100;index"`
	SpecName     string    `json:"spec_name" gorm:"column:spec_name;not null;size:150"`
	SpecValue    string    `json:"spec_value" gorm:"column:spec_value;type:text"`
	SpecUnit     string    `json:"spec_unit" gorm:"column:spec_unit;size:50"`
	DisplayOrder int       `json:"display_order" gorm:"column:display_order;default:0;index"`
	CreatedAt    time.Time `json:"created_at" gorm:"column:created_at;autoCreateTime"`
	UpdatedAt    time.Time `json:"updated_at" gorm:"column:updated_at;autoUpdateTime"`
	ScrapedAt    time.Time `json:"scraped_at" gorm:"column:scraped_at;autoCreateTime"`
}

// TableName specifies the table name for TrimSpecsInfo
func (TrimSpecsInfo) TableName() string {
	return "trim_specs_info"
}

// ConvertToSpecItem converts TrimSpecsInfo to SpecItem
func (tsi TrimSpecsInfo) ConvertToSpecItem() SpecItem {
	dataType := "text"
	if tsi.SpecValue != "" {
		// 简单的数据类型检测
		if len(tsi.SpecValue) > 0 {
			if tsi.SpecValue[0] >= '0' && tsi.SpecValue[0] <= '9' {
				dataType = "numeric"
			} else if tsi.SpecValue == "Yes" || tsi.SpecValue == "No" {
				dataType = "boolean"
			}
		}
	}

	return SpecItem{
		Name:         tsi.SpecName,
		Value:        tsi.SpecValue,
		Unit:         tsi.SpecUnit,
		DisplayOrder: tsi.DisplayOrder,
		DataType:     dataType,
	}
}

// TrimWithSpecs represents a trim with its specifications grouped by category
type TrimWithSpecs struct {
	TrimInfo       TrimInfo                   `json:"trim_info"`
	Specifications map[string][]TrimSpecsInfo `json:"specifications"` // 🔥 保留兼容性
	SpecsCount     int                        `json:"specs_count"`
}

// TrimResponse represents the response for the get_trims API
type TrimResponse struct {
	ModelName  string          `json:"model_name"`
	DetailURL  string          `json:"detail_url"`
	Trims      []TrimWithSpecs `json:"trims"`
	TotalTrims int             `json:"total_trims"`
	ScrapedAt  time.Time       `json:"scraped_at"`
	Message    string          `json:"message,omitempty"`
}
